package com.example.nonacademic_education.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.nonacademic_education.dao.AdminDao;
import com.example.nonacademic_education.dao.ProjectDao;
import com.example.nonacademic_education.dao.StudentDao;
import com.example.nonacademic_education.dao.TheClassDao;
import com.example.nonacademic_education.data.request.ProjectExcelVo;
import com.example.nonacademic_education.data.request.ProjectList;
import com.example.nonacademic_education.data.response.*;
import com.example.nonacademic_education.entity.Project;
import com.example.nonacademic_education.service.ProjectService;
import com.example.nonacademic_education.util.R;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author:yanghua
 * @Date:2023/4/18 19:44
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectDao, Project> implements ProjectService {
    @Resource
    private ProjectDao projectDao;
    @Resource
    private AdminDao adminDao;
    @Resource
    private TheClassDao theClassDao;
    @Resource
    private StudentDao studentDao;

    @Override
    public R addOne(Project project) {
        projectDao.insert(project);
        Map<String, Object> data = new HashMap<>();
        data.put("project", project);
        return R.ok(data, "添加成功");
    }

    @Override
    public R deleteOne(Long id) {
        projectDao.deleteOne(id);
        studentDao.deleteByProjectId(id);
        theClassDao.deleteByProjectId(id);
        return R.ok("删除成功");
    }

    @Override
    public R updateOne(Project project) {
        projectDao.updateById(project);
        Map<String, Object> data = new HashMap<>();
        data.put("data", project);
        return R.ok(data, "修改成功");
    }

    @Override
    public R getList(ProjectList projectList,Integer item) {
        if (projectList.getPage() < 1) {
            return R.error("页数不能小于1");
        }
        if (projectList.getDepartmentId()==null){
            projectList.setDepartmentId(adminDao.getDepartmentIdByUsername(StpUtil.getLoginIdAsString()));
        }
        projectList.setPage((projectList.getPage() - 1) * projectList.getSize());
        List<ProjectAllDto> list=new ArrayList<>();
        Integer total=0;
        if (item==0){
            list= projectDao.getList(projectList);
            total= projectDao.getNumber(projectList);
        }else if (item==1){
            List<Long> infoMissIds=projectDao.getInfoMissIds();
            if (!infoMissIds.isEmpty()){
                list= projectDao.getListByInfoMiss(projectList,infoMissIds);
                total= projectDao.getNumberByInfoMiss(projectList,infoMissIds);
            }
        }else if (item==2){
            List<Long> fileMissIds=projectDao.getFileMissIds();
            if (!fileMissIds.isEmpty()){
                list= projectDao.getListByFileMiss(projectList,fileMissIds);
                total= projectDao.getNumberByFileMiss(projectList,fileMissIds);
            }
        }
        Map<String, Object> data = new HashMap<>();
        data.put("list", list);
        data.put("total", total);
        return R.ok(data, "查询成功");
    }

    @Override
    public R getIdAndName(ProjectList projectList) {
        if (projectList.getDepartmentId()==null){
            projectList.setDepartmentId(adminDao.getDepartmentIdByUsername(StpUtil.getLoginIdAsString()));
        }
        List<ProjectDto> list = projectDao.getIdAndName(projectList);
        Integer total = projectDao.getNumber(projectList);
        Map<String, Object> data = new HashMap<>();
        data.put("list", list);
        data.put("total", total);
        return R.ok(data, "查询成功");
    }

    @Override
    public void exportStatisticsExcel(ProjectExcelVo projectExcelVo, HttpServletResponse response) throws IOException {
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        List<ProjectExcelDto> data = projectDao.exportStatisticsExcel(projectExcelVo);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("培训项目开办情况", "UTF-8").replaceAll("\\+", "%20");
        //response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), ProjectExcelDto.class).sheet("数据").doWrite(data);
    }

    @Override
    public void getTemplate(HttpServletResponse response) throws IOException {
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        List<ProjectImportDto> data = new ArrayList<>();
        ProjectImportDto projectImportDto = new ProjectImportDto();
        projectImportDto.setName("Office培训");
        projectImportDto.setDepartmentName("计算机学院");
        projectImportDto.setYear(2023);
        projectImportDto.setAdminName("杨XX");
        projectImportDto.setContactName("王XX");
        projectImportDto.setContactPhone("136XXXX4514");
        projectImportDto.setStartDateString("2023-05-01");
        projectImportDto.setEndDateString("2023-06-20");
        projectImportDto.setEstablishType("独立办学");
        projectImportDto.setEstablishAddress("田家炳A104");
        projectImportDto.setCharge("5.6");
        projectImportDto.setTuitionFee("200.0");
        projectImportDto.setTrainingNum("50");
        projectImportDto.setCooperation("XXX公司");
        projectImportDto.setNote("");
        data.add(projectImportDto);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("批量导入项目开办信息模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), ProjectImportDto.class).sheet("模板").doWrite(data);
    }

    @Override
    public R importProject(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), ProjectImportDto.class, new ReadListener<ProjectImportDto>() {
            /**
             * 单次缓存的数据量
             */
            public static final int BATCH_COUNT = 50;
            /**
             *临时存储
             */
            private List<ProjectImportDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

            @Override
            public void invoke(ProjectImportDto data, AnalysisContext context) {
                //处理数据
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    //System.out.println(data.getAdminName());
                    //System.out.println(data.getStartDateString());
                    Date startDate=null;
                    if (data.getStartDateString()!=null) {
                        startDate= dateFormat.parse(data.getStartDateString());
                    }
                    data.setStartDate(startDate);
                } catch (ParseException e) {
                    data.setStartDate(null);
                    e.printStackTrace();
                }
                try {
                    Date endDate=null;
                    if (data.getEndDateString()!=null) {
                        endDate= dateFormat.parse(data.getEndDateString());
                    }
                    data.setEndDate(endDate);
                } catch (ParseException e) {
                    data.setEndDate(null);
                    e.printStackTrace();
                }
                cachedDataList.add(data);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    saveData();
                    // 存储完成清理 list
                    cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                saveData();
            }

            /**
             * 加上存储数据库
             */
            private void saveData() {
                if (cachedDataList.size() > 0) {
                    projectDao.importProject(cachedDataList);
                    //System.out.println();
                }
            }
        }).sheet().doRead();
        return R.ok("批量导入项目开办信息成功");
    }
}
